1 module printers;
2 import defs;
3 
4 string toString(ref OGLDocumentation ctx, string linetabs="") {
5 	import std.string : splitLines, strip;
6 	with(ctx) {
7 		string sublinetabs = linetabs ~ "|    ";
8 		string suffix;
9 
10 		switch(type) {
11 			case OGLDocumentationType.LookupParameter:
12 				suffix = "^parameter";
13 				goto case OGLDocumentationType.Container;
14 			case OGLDocumentationType.LookupConstant:
15 				suffix = "^constant";
16 				goto case OGLDocumentationType.Container;
17 			case OGLDocumentationType.LookupFunction:
18 				suffix = "^function";
19 				goto case OGLDocumentationType.Container;
20 			case OGLDocumentationType.Title:
21 				suffix = "title";
22 				goto case OGLDocumentationType.Container;
23 				
24 			case OGLDocumentationType.TableContainer:
25 				import std.conv : text;
26 				suffix = "table>[cols=" ~ value_numcols.text ~ "]";
27 				goto case OGLDocumentationType.Container;
28 			case OGLDocumentationType.TableHeader:
29 				suffix = "head";
30 				goto case OGLDocumentationType.Container;
31 			case OGLDocumentationType.TableBody:
32 				suffix = "body";
33 				goto case OGLDocumentationType.Container;
34 			case OGLDocumentationType.TableRow:
35 				suffix = "row";
36 				goto case OGLDocumentationType.Container;
37 			case OGLDocumentationType.TableEntry:
38 				suffix = "entry";
39 				goto case OGLDocumentationType.Container;
40 			case OGLDocumentationType.Trademark:
41 				suffix = "™";
42 				goto case OGLDocumentationType.Container;
43 			case OGLDocumentationType.Copyright:
44 				suffix = "©";
45 				goto case OGLDocumentationType.Container;
46 			case OGLDocumentationType.StyleContainer:
47 				suffix = "style>" ~ value_string;
48 				goto case OGLDocumentationType.Container;
49 			case OGLDocumentationType.StyleCode:
50 				suffix = "code";
51 				goto case OGLDocumentationType.Container;
52 			case OGLDocumentationType.Footnote:
53 				suffix = "\\/footnote";
54 				goto case OGLDocumentationType.Container;
55 			case OGLDocumentationType.InlineEquation:
56 				suffix = "|<equation";
57 				goto case OGLDocumentationType.Container;
58 			
59 			case OGLDocumentationType.MathMLContainer:
60 				suffix = "MathML[_]";
61 				goto case OGLDocumentationType.Container;
62 			case OGLDocumentationType.MathML_MI:
63 				suffix = "MathML:mi";
64 				goto case OGLDocumentationType.Container;
65 			case OGLDocumentationType.MathML_mn:
66 				suffix = "MathML:mn";
67 				goto case OGLDocumentationType.Container;
68 			case OGLDocumentationType.MathML_mrow:
69 				suffix = "MathML:mrow";
70 				goto case OGLDocumentationType.Container;
71 			case OGLDocumentationType.MathML_msup:
72 				suffix = "MathML:msup";
73 				goto case OGLDocumentationType.Container;
74 			case OGLDocumentationType.MathML_mo:
75 				suffix = "MathML:mo";
76 				goto case OGLDocumentationType.Container;
77 			case OGLDocumentationType.MathML_msub:
78 				suffix = "MathML:msub";
79 				goto case OGLDocumentationType.Container;
80 			case OGLDocumentationType.MathML_mfrac:
81 				suffix = "MathML:mfrac";
82 				goto case OGLDocumentationType.Container;
83 			case OGLDocumentationType.MathML_mtable:
84 				suffix = "MathML:mtable[" ~ value_string ~ "]";
85 				goto case OGLDocumentationType.Container;
86 			case OGLDocumentationType.MathML_mtr:
87 				suffix = "MathML:mtr";
88 				goto case OGLDocumentationType.Container;
89 			case OGLDocumentationType.MathML_mtd:
90 				suffix = "MathML:mtd[" ~ value_string ~ "]";
91 				goto case OGLDocumentationType.Container;
92 			case OGLDocumentationType.MathML_mspace:
93 				suffix = "MathML:mspace[ " ~ value_string ~ " ]";
94 				goto case OGLDocumentationType.Container;
95 			case OGLDocumentationType.MathML_mtext:
96 				suffix = "MathML:mtext[ " ~ value_string ~ " ]";
97 				goto case OGLDocumentationType.Container;
98 			case OGLDocumentationType.MathML_apply:
99 				suffix = "MathML:apply";
100 				goto case OGLDocumentationType.Container;
101 			case OGLDocumentationType.MathML_csymbol:
102 				suffix = "MathML:csymbol";
103 				goto case OGLDocumentationType.Container;
104 			case OGLDocumentationType.MathML_infinity:
105 				suffix = "MathML:infinity ∞";
106 				goto case OGLDocumentationType.Container;
107 			case OGLDocumentationType.MathML_mover:
108 				suffix = "MathML:mover";
109 				goto case OGLDocumentationType.Container;
110 			case OGLDocumentationType.MathML_munderover:
111 				suffix = "MathML:munderover";
112 				goto case OGLDocumentationType.Container;
113 			case OGLDocumentationType.MathML_msqrt:
114 				suffix = "MathML:msqrt";
115 				goto case OGLDocumentationType.Container;
116 
117 			case OGLDocumentationType.IndexList:
118 				suffix = "X. []";
119 				goto case OGLDocumentationType.Container;
120 			case OGLDocumentationType.IndexItem:
121 				suffix = "X. Y";
122 				goto case OGLDocumentationType.Container;
123 
124 			case OGLDocumentationType.List:
125 				suffix = "- []";
126 				goto case OGLDocumentationType.Container;
127 			case OGLDocumentationType.ListItem:
128 				suffix = "- X";
129 				goto case OGLDocumentationType.Container;
130 
131 			case OGLDocumentationType.Link:
132 				suffix = "link <-> " ~ value_string;
133 				goto case OGLDocumentationType.Container;
134 			case OGLDocumentationType.StyleSuperScript:
135 				suffix = "^^superscript";
136 				goto case OGLDocumentationType.Container;
137 			case OGLDocumentationType.StyleSubScript:
138 				suffix = "	⌄	⌄subscript";
139 				goto case OGLDocumentationType.Container;
140 				
141 			case OGLDocumentationType.Paragraph:
142 			case OGLDocumentationType.Container:
143 				string ret;
144 				ret = linetabs ~ "|----" ~ suffix ~ "\n";
145 				foreach(i, child; value_children)
146 					ret ~= child.toString(sublinetabs);
147 				return ret;
148 
149 			case OGLDocumentationType.Text:
150 				if (suffix is null)
151 					suffix = "#text";
152 				string ret = linetabs ~ "|----" ~ suffix;
153 				foreach(line; value_string.splitLines) {
154 					string linestripped = line.strip;
155 					if (linestripped.length > 0)
156 						ret ~= "\n" ~ sublinetabs ~ linestripped;
157 				}
158 				return ret ~ "\n";
159 				
160 			case OGLDocumentationType.MathML_mfenced:
161 				string ret;
162 				ret = linetabs ~ "|----MathML:mfenced |--| \n";
163 				ret ~= sublinetabs ~ "open={ " ~ value_string ~ " } close={ " ~ value_string2 ~ " }\n";
164 				foreach(i, child; value_children)
165 					ret ~= child.toString(sublinetabs);
166 				return ret;
167 				
168 			case OGLDocumentationType.MathML_floor:
169 				return "|__floor__\n";
170 				
171 			case OGLDocumentationType.Unknown:
172 			default:
173 				suffix = "#ERROR";
174 				goto case OGLDocumentationType.Text;
175 
176 		}
177 	}
178 }
179 
180 bool haveAnErrorNode(ref OGLFunctionFamily ctx) {
181 	if (ctx.docs_copyright.haveAnErrorNode)
182 		return true;
183 	else if (ctx.docs_description.haveAnErrorNode)
184 		return true;
185 	else if (ctx.docs_notes.haveAnErrorNode)
186 		return true;
187 	else if (ctx.docs_seealso.haveAnErrorNode)
188 		return true;
189 
190 	foreach(param; ctx.docs_parameters) {
191 		if (param.documentation.haveAnErrorNode)
192 			return true;
193 	}
194 	
195 	return false;
196 }
197 
198 bool haveAnErrorNode(ref OGLDocumentation ctx) {
199 	switch(ctx.type) {
200 		case OGLDocumentationType.LookupParameter:
201 		case OGLDocumentationType.LookupConstant:
202 		case OGLDocumentationType.LookupFunction:
203 		case OGLDocumentationType.TableContainer:
204 		case OGLDocumentationType.TableHeader:
205 		case OGLDocumentationType.TableBody:
206 		case OGLDocumentationType.TableRow:
207 		case OGLDocumentationType.TableEntry:
208 		case OGLDocumentationType.StyleContainer:
209 		case OGLDocumentationType.StyleCode:
210 		case OGLDocumentationType.StyleSuperScript:
211 		case OGLDocumentationType.StyleSubScript:
212 		case OGLDocumentationType.Paragraph:
213 		case OGLDocumentationType.Footnote:
214 		case OGLDocumentationType.Container:
215 		case OGLDocumentationType.InlineEquation:
216 		case OGLDocumentationType.MathMLContainer:
217 		case OGLDocumentationType.MathML_MI:
218 		case OGLDocumentationType.MathML_mfenced:
219 		case OGLDocumentationType.MathML_mn:
220 		case OGLDocumentationType.MathML_mrow:
221 		case OGLDocumentationType.MathML_msup:
222 		case OGLDocumentationType.MathML_mo:
223 		case OGLDocumentationType.MathML_msub:
224 		case OGLDocumentationType.MathML_mfrac:
225 		case OGLDocumentationType.MathML_mtable:
226 		case OGLDocumentationType.MathML_mtr:
227 		case OGLDocumentationType.MathML_mtd:
228 		case OGLDocumentationType.MathML_mspace:
229 		case OGLDocumentationType.MathML_mtext:
230 		case OGLDocumentationType.MathML_apply:
231 		case OGLDocumentationType.MathML_floor:
232 		case OGLDocumentationType.MathML_csymbol:
233 		case OGLDocumentationType.MathML_infinity:
234 		case OGLDocumentationType.MathML_mover:
235 		case OGLDocumentationType.MathML_munderover:
236 		case OGLDocumentationType.MathML_msqrt:
237 		case OGLDocumentationType.Trademark:
238 		case OGLDocumentationType.IndexList:
239 		case OGLDocumentationType.IndexItem:
240 		case OGLDocumentationType.List:
241 		case OGLDocumentationType.ListItem:
242 		case OGLDocumentationType.Copyright:
243 		case OGLDocumentationType.Link:
244 			foreach(ref child; ctx.value_children) {
245 				if (child.haveAnErrorNode)
246 					return true;
247 			}
248 			return false;
249 		case OGLDocumentationType.Unknown:
250 			return true;
251 		default:
252 			return false;
253 	}
254 }
255 
256 void print_misc_info(OGLFunctionFamily[] familyOfFunctions, OGLEnumGroup[] enums) {
257 	import std.stdio : writeln;
258 	
259 	writeln("Information:");
260 	
261 	uint numFunctions, numGroupedEnums, numGroupEnum, numEnums;
262 	foreach(family; familyOfFunctions)
263 		numFunctions += family.functions.length;
264 	foreach(grp; enums) {
265 		if (grp.name.length > 0) {
266 			numGroupedEnums++;
267 			numGroupEnum += grp.enums.length;
268 		}
269 
270 		numEnums += grp.enums.length;
271 	}
272 
273 	writeln("\tThere is a total of ", familyOfFunctions.length, " function families loaded.");
274 	writeln("\tOf these there are a total of ", numFunctions, " functions these families provide.");
275 	writeln("\tThere is a total of ", numGroupedEnums, " enums groups loaded.");
276 	writeln("\tOf these there are a total of ", numGroupEnum, " enums in these groups.");
277 	writeln("\tIn total there are ", numEnums, " number of enums in total.");
278 
279 	writeln;
280 }
281 
282 void print_everything(OGLFunctionFamily[] functionFamilies, string forName=null) {
283 	import std.stdio : write, writeln;
284 	
285 	writeln("Families:");
286 	foreach(family; functionFamilies) {
287 		if (forName !is null && family.familyOfFunction != forName) continue;
288 
289 		writeln("- ", family.fromFilename, "[", family.familyOfFunction, "]");
290 		
291 		writeln("\tCopyright: ", family.copyright);
292 		writeln(family.docs_copyright.toString("\t"));
293 
294 		writeln("\tDescription:");
295 		writeln(family.docs_description.toString("\t"));
296 		writeln("\tSee_Also:");
297 		writeln(family.docs_seealso.toString("\t"));
298 
299 		writeln("\tParamater documentation:");
300 		foreach(param; family.docs_parameters) {
301 			write("\t- ");
302 			foreach(i, appliesToName; param.appliesToNames) {
303 				if (i > 0)
304 					write(", ");
305 				write(appliesToName);
306 			}
307 			writeln;
308 
309 			write(param.documentation.toString("\t"));
310 		}
311 		writeln;
312 
313 		writeln("\tFunction varients:");
314 		foreach(func; family.functions) {
315 			write("\t- ", func.returnType, " ", func.name, "(");
316 
317 			foreach(i, argType; func.argTypes) {
318 				if (i > 0)
319 					write(", ");
320 				write(argType, " ", func.argNames[i]);
321 			}
322 
323 			writeln(")");
324 		}
325 		writeln;
326 
327 		writeln("\tNotes:");
328 		write(family.docs_notes.toString("\t"));
329 		writeln;
330 
331 		writeln("\tErrors:");
332 		write(family.docs_errors.toString("\t"));
333 	}
334 	
335 	writeln;
336 }
337 
338 void print_only_with_errors(OGLFunctionFamily[] functionFamilies) {
339 	import std.stdio : write, writeln;
340 
341 	writeln("Errors, Families:");
342 	foreach(family; functionFamilies) {
343 		if (!family.haveAnErrorNode) continue;
344 		
345 		writeln("- ", family.fromFilename, "[", family.familyOfFunction, "]");
346 		
347 		writeln("\tCopyright: ", family.copyright);
348 		writeln(family.docs_copyright.toString("\t"));
349 
350 		writeln("\tDescription:");
351 		writeln(family.docs_description.toString("\t"));
352 		writeln("\tSee_Also:");
353 		writeln(family.docs_seealso.toString("\t"));
354 
355 		writeln("\tParamater documentation:");
356 		foreach(param; family.docs_parameters) {
357 			write("\t- ");
358 			foreach(i, appliesToName; param.appliesToNames) {
359 				if (i > 0)
360 					write(", ");
361 				write(appliesToName);
362 			}
363 			writeln;
364 
365 			write(param.documentation.toString("\t"));
366 		}
367 		writeln;
368 
369 		writeln("\tFunction varients:");
370 		foreach(func; family.functions) {
371 			write("\t- ", func.returnType, " ", func.name, "(");
372 
373 			foreach(i, argType; func.argTypes) {
374 				if (i > 0)
375 					write(", ");
376 				write(argType, " ", func.argNames[i]);
377 			}
378 
379 			writeln(")");
380 		}
381 		writeln;
382 
383 		writeln("\tNotes:");
384 		write(family.docs_notes.toString("\t"));
385 		writeln;
386 		
387 		writeln("\tErrors:");
388 		write(family.docs_errors.toString("\t"));
389 	}
390 }